package com.kzy.demoadmin.web.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.kzy.demoadmin.web.entity.LoginParam;
import com.kzy.demoadmin.web.entity.User;
import com.kzy.demoadmin.web.entity.UserPageQuery;
import com.kzy.demoadmin.web.entity.VerifyCodeEntity;
import com.kzy.demoadmin.web.exception.BizException;
import com.kzy.demoadmin.web.mapper.UserMapper;
import com.kzy.demoadmin.web.service.UserService;
import com.kzy.demoadmin.web.utils.JwtTokenUtils;
import com.wf.captcha.ArithmeticCaptcha;
import com.wf.captcha.base.Captcha;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private StringRedisTemplate redisTemplate; // 注入 StringRedisTemplate

    /**
     * 新增用户
     * @param user
     * @return
     */
    @Override
    public void add(User user) {
        //1、用户名不能为空
        if (user.getUsername() == null || "".equals(user.getUsername())){
            throw new BizException("用户名不能为空");
        }
        //2、进行重复性判断，同一用户名不能重复
        User u = userMapper.findByUsername(user.getUsername());
        if (u != null){
            //已经有了，这里提示不允许新增
            throw new BizException("用户名已经存在,请勿重复添加");
        }
        //3、保存用户
        if(user.getPassword()==null || "".equals(user.getPassword())){
            user.setPassword("123456");
        }

        //4、判断状态是否有值
        if (user.getStatus() == null){
            user.setStatus(1);
        }

        //给用户一个默认角色
        if (user.getRole() == null){
            user.setRole("ROLE_USER");
        }

        userMapper.insertUser(user);
    }

    /**
     * 根据id查询用户
     * @param integer
     * @return
     */
    @Override
    public User findById(Integer integer) {
        return userMapper.findById(integer);
    }

    /**
     * 生成验证码
     * @return
     */
    @Override
    public VerifyCodeEntity generateVerifyCode() {
        // 创建验证码对象
        Captcha captcha = new ArithmeticCaptcha();

        // 生成验证码编号
        String verifyCodeKey = UUID.randomUUID().toString();
        String verifyCode = captcha.text();

        // 获取验证码图片，构造响应结果
        VerifyCodeEntity verifyCodeEntity = new VerifyCodeEntity(verifyCodeKey, captcha.toBase64(), verifyCode);

        // 存入Redis，设置120s过期
        redisTemplate.opsForValue().set(verifyCodeKey, verifyCode, 120, TimeUnit.SECONDS);

        return verifyCodeEntity;
    }

    /**
     * 分页查询用户列表
     */
    @Override
    public PageInfo<User> getUserPage(UserPageQuery query) {
//      1.开启分页
        PageHelper.startPage(query.getPageNo(), query.getPageSize());
        List<User> list = userMapper.searchBy(query);
        return new PageInfo<>(list);
    }

    /**
     * 删除用户
     * @param id
     * @return
     */
    @Override
    public int deleteById(Integer id) {
        //根据id查询是否为超级管理员
        User u = userMapper.findById(id);
        if ("admin".equals(u.getUsername())){
            throw new BizException("超级管理员不能删除");
        }
        return userMapper.deleteById(id);
    }

    /**
     * 修改用户
     * @param user
     */
    @Override
    public void edit(User user) {
        //1、用户名不能为空
        if (user.getUsername() == null || "".equals(user.getUsername())){
            throw new BizException("用户名不能为空");
        }
        
        //2、密码不能为空
        if (user.getPassword() == null || "".equals(user.getPassword())){
            throw new BizException("密码不能为空");
        }
        
        //3、用户名不能重复
        User u = userMapper.findByUsername(user.getUsername());
        if (u != null && !u.getId().equals(user.getId())){
            throw new BizException("用户名已经存在,请勿重复添加");
        }
        //4、修改用户
        userMapper.edit(user);
    }

    /**
     * 登录
     * @param loginParam
     * @return
     */
    @Override
    public User login(LoginParam loginParam) {
        //1、进行非空判断
        if (loginParam.getUsername() == null || "".equals(loginParam.getUsername())){
            throw new BizException("用户名不能为空");
        }
        if (loginParam.getPassword() == null || "".equals(loginParam.getPassword())){
            throw new BizException("密码不能为空");
        }
        //获取用户验证码
        String actual = loginParam.getVerifyCode();

        // 判断验证码是否过期
        if (redisTemplate.getExpire(loginParam.getVerifyCodeKey(), TimeUnit.SECONDS) < 0) {
//            throw new RuntimeException("验证码过期");
            Long expire = redisTemplate.getExpire(loginParam.getVerifyCodeKey(), TimeUnit.SECONDS);
            if (expire == -2) {
                log.error("Verify code key not found: {}", loginParam.getVerifyCodeKey());
                throw new RuntimeException("验证码不存在");
            } else if (expire <= 0) {
                log.error("Verify code expired for key: {}", loginParam.getVerifyCodeKey());
                throw new RuntimeException("验证码过期");
            }
        }
        // 从redis读取验证码并删除缓存
        String expect = (String) redisTemplate.opsForValue().get(loginParam.getVerifyCodeKey());
        redisTemplate.delete(loginParam.getVerifyCodeKey());

        // 比较用户输入的验证码和缓存中的验证码是否一致，不一致则抛错
        if (!StringUtils.hasText(expect) || !StringUtils.hasText(actual) || !actual.equalsIgnoreCase(expect)) {
            throw new RuntimeException("验证码错误");
        }

        //2、从数据库里根据用户名查询用户
        User u =  userMapper.findByNameAndPassword(loginParam.getUsername(), loginParam.getPassword());
        if (u == null){
            throw new BizException("用户名或密码错误");
        }else if (u.getStatus() == 0){
            throw new BizException("用户被禁用");
        }
        //生成 token并跟u返回
        String token = JwtTokenUtils.genToken(u.getId().toString(), u.getPassword());
        u.setToken( token);
        return u;
    }
}
